/*  For our final example, server5.c, 
    we include the sys/time.h and sys/ioctl.h headers in place of signal.h
    in our last program and declare some extra variables to deal with select.  */

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>

int selfds[10];

int main()
{
    int server_sockfd, client_sockfd;
    int server_len, client_len;
    struct sockaddr_in server_address;
    struct sockaddr_in client_address;
    int result;
    fd_set readfds, testfds;
	int fdMax = 0;
	int i;
	int flag;

	memset(selfds, 0, sizeof(selfds));

/*  Create and name a socket for the server.  */

    server_sockfd = socket(AF_INET, SOCK_STREAM, 0);

	for(i = 0; i < 10; i++){
		if(!selfds[i]) {
			selfds[i] = server_sockfd;
			break;
		}
	}
	
	flag = 1;
	int len = sizeof(int);
	if (setsockopt(server_sockfd, SOL_SOCKET, SO_REUSEADDR, &flag, len) < 0)
	{
		perror("setsockopt SO_REUSEADDR failure\n");
	}

	if(fdMax < server_sockfd + 1)
		fdMax = server_sockfd + 1;

    server_address.sin_family = AF_INET;
    server_address.sin_addr.s_addr = htonl(INADDR_ANY);
    server_address.sin_port = htons(9752);
    server_len = sizeof(server_address);

    bind(server_sockfd, (struct sockaddr *)&server_address, server_len);

/*  Create a connection queue and initialize readfds to handle input from server_sockfd.  */

    listen(server_sockfd, 5);

    FD_ZERO(&readfds);
    FD_SET(server_sockfd, &readfds);



/*  Now wait for clients and requests.
    Since we have passed a null pointer as the timeout parameter, no timeout will occur.
    The program will exit and report an error if select returns a value of less than 1.  */

    while(1) {
        char *ch;
		ch = malloc(100000);
        int fd;
        
		int nread;

        testfds = readfds;

        printf("server waiting, maxfd=%d\n", fdMax);

		for(fd = 0; fd < 10 && selfds[fd]; fd++)
			printf("selfds[%d]=%d\n", fd, selfds[fd]);

        result = select(fdMax, &testfds, (fd_set *)0, 
            (fd_set *)0, (struct timeval *) 0);

        if(result < 1) {
            perror("server5");
            exit(1);
        }

/*  Once we know we've got activity,
    we find which descriptor it's on by checking each in turn using FD_ISSET.  */

		printf("select activity ... \n");

        for(fd = 0; fd < 10 && selfds[fd]; fd++) {
            if(FD_ISSET(selfds[fd],&testfds)) {

				printf("FD_ISSET is %d\n", selfds[fd]);

                if(selfds[fd] == server_sockfd) {
                    client_len = sizeof(client_address);
                    client_sockfd = accept(server_sockfd, 
                        (struct sockaddr *)&client_address, &client_len);


					flag = fcntl(client_sockfd, F_GETFL, 0);
					flag |= O_NONBLOCK;
//					fcntl(client_sockfd, F_SETFL, 0);

                    FD_SET(client_sockfd, &readfds);
					if(fdMax < client_sockfd + 1)
						fdMax = client_sockfd + 1;

					int j;
					for(j = 0; j < 10 && selfds[j]; j++){}
					if (j==10)
						printf("Error: fd is full!\n");
					else
						selfds[j] = client_sockfd;

                    printf("adding client on fd %d\n", client_sockfd);
                }

                else {


                    ioctl(selfds[fd], FIONREAD, &nread);

                    if(nread == 0) {
                        close(selfds[fd]);
                        FD_CLR(selfds[fd], &readfds);
                        printf("removing client on fd %d\n", selfds[fd]);
                    }

                    else {
						int rdnum;	
						printf("\nrecv %d bytes ...\n", 50000);
                        rdnum = read(selfds[fd], ch, 50000);
						if (rdnum < 0)
							printf("%s\n", strerror(errno));
                        printf("recv client %d \"%d\"\n", selfds[fd], rdnum);
						printf("sleep few seconds...\n");
						
						printf("\nrecv %d bytes ...\n", 50000);
                        rdnum = read(selfds[fd], ch, 50000);
						if (rdnum < 0)
							printf("%s\n", strerror(errno));
                        printf("recv client %d \"%d\"\n", selfds[fd], rdnum);
						printf("sleep few seconds...\n");
						sleep(30);
//                        ch++;
//                        write(selfds[fd], &ch, 1);
                    }
                }
            }
    }
}
}
